package logging

import (
	"fmt"
	"gitee.com/huerbiao/robot/pkg/logger"
	error2 "gitee.com/huerbiao/robot/service/error"
	"github.com/gin-gonic/gin"
	"github.com/go-errors/errors"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
	"net/http/httputil"
	"runtime"
	"time"
)

func Recovery(f func(c *gin.Context, err interface{})) gin.HandlerFunc {

	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				httprequest, _ := httputil.DumpRequest(c.Request, false)
				goErr := errors.Wrap(err, 3)
				reset := string([]byte{27, 91, 48, 109})
				logger.Panic(fmt.Sprintf(`[Recovery] panic recovered:Request : %s, Error :%s, Stack :%s,Reset :%s`, httprequest, goErr.Error(), goErr.Stack(), reset))
				f(c, err)
			}
		}()
		c.Next() // execute all the handlers
	}
}

func RecoveryHandler(c *gin.Context, err interface{}) {
	c.JSON(http.StatusOK, gin.H{
		"code": error2.ServerErrorCode,
		"msg":  err,
		"body": map[string]interface{}{},
	})
	c.Abort()
}

func RecoveryGrpcHandler(p interface{}) (err error) {
	buf := make([]byte, 64<<10)
	buf = buf[:runtime.Stack(buf, false)]
	log := time.Now().Format("2006-01-02 15:04:05.000")
	log += " -- stack:" + string(buf)

	logger.Error(log)

	return status.Errorf(codes.Unknown, "panic triggered: %v", p)
}
